﻿using MyK3CloudCore.IOC.Types;
using SQLBuilder.Enums;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace MyK3CloudCore.IOC.K3Client
{
    /// <summary>
    /// 链式请求
    /// </summary>
    /// <typeparam name="T">表单类</typeparam>
    public partial interface IK3Queryable<T>
    {
        /// <summary>
        /// 筛选
        /// </summary>
        IK3Queryable<T> Where(Expression<Func<T, bool>> expression);
        /// <summary>
        /// 筛选
        /// </summary>
        IK3Queryable<T> WhereIF(bool isWhere, Expression<Func<T, bool>> expression);
        /// <summary>
        /// 排序
        /// </summary>
        IK3Queryable<T> OrderBy(Expression<Func<T, object>> expression, OrderType[] orders = default);
        /// <summary>
        /// 跳过 count 行
        /// </summary>
        IK3Queryable<T> Skip(int count);
        /// <summary>
        /// 取 count 行
        /// </summary>
        IK3Queryable<T> Take(int count);
        /// <summary>
        /// 配置缓存
        /// </summary>
        /// <param name="cacheDurationInSeconds">缓存 秒</param>
        IK3Queryable<T> WithCache(int cacheDurationInSeconds = int.MaxValue);
        /// <summary>
        /// 配置缓存
        /// </summary>
        /// <param name="cacheKey">自定义缓存键</param>
        /// <param name="cacheDurationInSeconds">缓存 秒</param>
        /// <returns></returns>
        IK3Queryable<T> WithCache(string cacheKey, int cacheDurationInSeconds = int.MaxValue);
        /// <summary>
        /// 返回第一条元数据
        /// </summary>
        /// <returns></returns>
        Task<T> FirstAsync();
        /// <summary>
        /// 返回数据(同步)
        /// </summary>
        List<T> ToList();
        /// <summary>
        /// 返回数据(异步)
        /// </summary>
        Task<List<T>> ToListAsync();
        /// <summary>
        /// 按页码返回数据(异步)
        /// </summary>
        /// <param name="pageNumber">页码</param>
        /// <param name="pageSize">每页大小</param>
        /// <returns></returns>
        Task<List<T>> ToPageListAsync(int pageNumber, int pageSize);

        /// <summary>
        /// 按页码返回数据(异步)
        /// </summary>
        /// <param name="pageNumber">页码</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="totalNumber">返回总条数</param>
        /// <returns></returns>
        Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, Refasync<int> totalNumber);
        /// <summary>
        /// 按页码返回数据(异步)
        /// </summary>
        /// <param name="pageNumber">页码</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="countField">自定义统计条数字段</param>
        /// <param name="totalNumber">返回总条数</param>
        /// <returns></returns>
        Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, string countField, Refasync<int> totalNumber);
        /// <summary>
        /// 按页码返回数据(异步)
        /// </summary>
        /// <param name="pageNumber">页码</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="selector">自定义统计条数字段</param>
        /// <param name="totalNumber">返回总条数</param>
        /// <returns></returns>
        Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, Expression<Func<T, object>> selector, Refasync<int> totalNumber);
        /// <summary>
        /// 按页码返回数据(异步)
        /// </summary>
        /// <param name="pageNumber">页码</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="totalNumber">返回总条数</param>
        /// <param name="totalPage">返回总页数</param>
        /// <returns></returns>
        Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, Refasync<int> totalNumber, Refasync<int> totalPage);
        /// <summary>
        /// 返回记录条数
        /// </summary>
        /// <returns></returns>
        Task<int> CountAsync();
        /// <summary>
        /// 返回记录条数
        /// </summary>
        /// <param name="countField">计数字段</param>
        Task<int> CountAsync(string countField);
        /// <summary>
        /// 返回记录条数
        /// </summary>
        /// <param name="selector">计数字段</param>
        /// <returns></returns>
        Task<int> CountAsync(Expression<Func<T, object>> selector);
        /// <summary>
        /// 汇总
        /// </summary>
        /// <param name="sumFiled">汇总字段</param>
        /// <returns></returns>
        Task<Dictionary<string, decimal>> SumAsync(params string[] sumFiled);
        /// <summary>
        /// 汇总
        /// </summary>
        /// <param name="selector">汇总字段</param>
        /// <returns></returns>
        Task<Dictionary<string, decimal>> SumAsync(Expression<Func<T, object>> selector);
        IK3Queryable<T> Clone();

    }
}
